package com.easymeeting.controller;

import java.util.List;
import java.util.Optional;

import com.easymeeting.annotation.GlobalInterceptor;
import com.easymeeting.entity.dto.MessageSendDto;
import com.easymeeting.entity.dto.TokenUserInfoDto;
import com.easymeeting.entity.enums.MeetingMemberStatusEnum;
import com.easymeeting.entity.enums.MeetingStatusEnum;
import com.easymeeting.entity.enums.MessageSend2TypeEnum;
import com.easymeeting.entity.enums.ResponseCodeEnum;
import com.easymeeting.entity.po.MeetingMember;
import com.easymeeting.entity.query.MeetingInfoQuery;
import com.easymeeting.entity.po.MeetingInfo;
import com.easymeeting.entity.query.MeetingMemberQuery;
import com.easymeeting.entity.vo.PaginationResultVO;
import com.easymeeting.entity.vo.ResponseVO;
import com.easymeeting.exception.BusinessException;
import com.easymeeting.service.MeetingInfoService;
import com.easymeeting.service.MeetingMemberService;
import com.easymeeting.utils.StringTools;
import com.easymeeting.websocket.message.MessageHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.security.auth.message.MessageInfo;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

/**
 * 会议信息 Controller
 */
@RestController()
@RequestMapping("/meeting")
public class MeetingInfoController extends ABaseController {

    @Resource
    private MeetingInfoService meetingInfoService;
    @Resource
    private MessageHandler messageHandler;
    @Resource
    private MeetingMemberService meetingMemberService;


    @RequestMapping("/loadMeeting")
    @GlobalInterceptor
    public ResponseVO loadMeeting(Integer pageNo) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        MeetingInfoQuery meetingInfoQuery = new MeetingInfoQuery();
        meetingInfoQuery.setPageNo(pageNo);
        meetingInfoQuery.setUserId(tokenUserInfoDto.getUserId());
        meetingInfoQuery.setQueryMemberCount(true);
        meetingInfoQuery.setOrderBy("m.create_time desc");
        PaginationResultVO resultVO = meetingInfoService.findListByPage(meetingInfoQuery);
        return getSuccessResponseVO(resultVO);
    }

    @RequestMapping("/quickMeeting")
    @GlobalInterceptor
    public ResponseVO quickMeeting(@NotNull Integer meetingNoType,
                                   @NotEmpty @Size(max = 100) String meetingName,
                                   @NotNull Integer joinType,
                                   @Max(5) String joinPassword) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        if (tokenUserInfoDto.getCurrentMeetingId() != null) {
            throw new BusinessException("还有未结束的会议");
        }
        MeetingInfo meetingInfo = new MeetingInfo();
        meetingInfo.setMeetingNo(meetingNoType == 0 ? tokenUserInfoDto.getMyMeetingNo() : StringTools.getMeetingNoOrMeetingId());
        meetingInfo.setMeetingName(meetingName);
        meetingInfo.setJoinType(joinType);
        meetingInfo.setJoinPassword(joinPassword);
        meetingInfo.setCreateUserId(tokenUserInfoDto.getUserId());
        meetingInfoService.quickMeeting(meetingInfo, tokenUserInfoDto.getNickName());

        tokenUserInfoDto.setCurrentMeetingId(meetingInfo.getMeetingId());
        tokenUserInfoDto.setCurrentNickName(tokenUserInfoDto.getNickName());

        resetTokenUserInfoDto(tokenUserInfoDto);
        return getSuccessResponseVO(meetingInfo.getMeetingId());
    }

    @RequestMapping("/joinMeeting")
    @GlobalInterceptor
    public ResponseVO joinMeeting(@NotNull Boolean videoOpen) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        meetingInfoService.joinMeeting(tokenUserInfoDto.getCurrentMeetingId(),
                tokenUserInfoDto.getUserId(),
                tokenUserInfoDto.getNickName(),
                tokenUserInfoDto.getSex(),
                videoOpen);
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/preJoinMeeting")
    @GlobalInterceptor
    public ResponseVO preJoinMeeting(
            String meetingNo,
            @NotEmpty String nickName,
            String password) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        meetingNo = meetingNo.replace(" ", "");
        tokenUserInfoDto.setCurrentNickName(nickName);
        String meetingId = meetingInfoService.preJoinMeeting(meetingNo, tokenUserInfoDto, password);
        return getSuccessResponseVO(meetingId);
    }

    @RequestMapping("/exitMeeting")
    @GlobalInterceptor
    public ResponseVO exitMeeting() {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        meetingInfoService.exitMeeting(tokenUserInfoDto, MeetingMemberStatusEnum.EXIT_MEETING);
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/kickOutMeeting")
    @GlobalInterceptor
    public ResponseVO kickOutMeeting(@NotEmpty String userId) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        meetingInfoService.forceExitMeeting(tokenUserInfoDto, userId, MeetingMemberStatusEnum.KICK_OUT);
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/blackMeeting")
    @GlobalInterceptor
    public ResponseVO blackMeeting(@NotEmpty String userId) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        meetingInfoService.forceExitMeeting(tokenUserInfoDto, userId, MeetingMemberStatusEnum.BLACKLIST);
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/getCurrentMeeting")
    @GlobalInterceptor
    public ResponseVO getCurrentMeeting() {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        if (StringTools.isEmpty(tokenUserInfoDto.getCurrentMeetingId())) {
            return getSuccessResponseVO(null);
        }
        MeetingInfo meetingInfo = meetingInfoService.getMeetingInfoByMeetingId(tokenUserInfoDto.getCurrentMeetingId());
        if (meetingInfo.getStatus().equals(MeetingStatusEnum.FINISHED.getStatus())) {
            return getSuccessResponseVO(null);
        }
        return getSuccessResponseVO(meetingInfo);
    }

    @RequestMapping("/finishMeeting")
    @GlobalInterceptor
    public ResponseVO finishMeeting(@NotEmpty String meetingId) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        this.meetingInfoService.finishMeeting(meetingId, tokenUserInfoDto.getUserId());
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/delMeetingRecord")
    @GlobalInterceptor
    public ResponseVO delMeetingRecord(@NotEmpty String meetingId) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        MeetingMember meetingMember = new MeetingMember();
        meetingMember.setMeetingStatus(MeetingMemberStatusEnum.DEL_MEETING.getStatus());

        MeetingMemberQuery meetingMemberQuery = new MeetingMemberQuery();
        meetingMemberQuery.setMeetingId(meetingId);
        meetingMemberQuery.setUserId(tokenUserInfoDto.getUserId());
        meetingMemberService.updateByParam(meetingMember, meetingMemberQuery);
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/loadMeetingMembers")
    @GlobalInterceptor
    public ResponseVO loadMeetingMembers(@NotEmpty String meetingId) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        MeetingMemberQuery meetingMemberQuery = new MeetingMemberQuery();
        meetingMemberQuery.setMeetingId(meetingId);
        List<MeetingMember> members = meetingMemberService.findListByParam(meetingMemberQuery);
        Optional<MeetingMember> first = members.stream().filter(item -> item.getUserId().equals(tokenUserInfoDto.getUserId())).findFirst(); // 9
        if (!first.isPresent()) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        return getSuccessResponseVO(members);
    }

    @RequestMapping("/reserveJoinMeeting")
    @GlobalInterceptor
    public ResponseVO reserveJoinMeeting(@NotEmpty String meetingId, @NotEmpty String nickName, String joinPassword) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        tokenUserInfoDto.setCurrentNickName(nickName);
        meetingInfoService.reserveJoinMeeting(meetingId, tokenUserInfoDto, joinPassword);
        return getSuccessResponseVO(meetingId);
    }

    @RequestMapping("/inviteMember")
    @GlobalInterceptor
    public ResponseVO inviteMember(@NotEmpty String selectContactIds) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        meetingInfoService.inviteMember(tokenUserInfoDto, selectContactIds);
        return getSuccessResponseVO(selectContactIds);
    }

    @RequestMapping("/acceptInvite")
    @GlobalInterceptor
    public ResponseVO acceptInvite(@NotEmpty String meetingId) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        meetingInfoService.acceptInvite(tokenUserInfoDto, meetingId);
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/sendOpenVideoChangeMessage")
    @GlobalInterceptor
    public ResponseVO sendOpenVideoChangeMessage(@NotNull Boolean openVideo) {
        TokenUserInfoDto tokenUserInfoDto = gettokenUserInfoDto();
        this.meetingInfoService.updateMemberOpenVideo(tokenUserInfoDto.getCurrentMeetingId(), tokenUserInfoDto.getUserId(), openVideo);
        return getSuccessResponseVO(null);
    }


}